package com.zz.tijian.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zz.tijian.entity.Users;
import com.zz.tijian.entity.req.CurrentUserInfo;
import com.zz.tijian.entity.req.ForgetDto;
import com.zz.tijian.entity.req.LoginDto;
import com.zz.tijian.entity.req.ResetPassDto;
import com.zz.tijian.entity.res.Result;
import com.zz.tijian.entity.res.UserDetailVo;
import com.zz.tijian.expections.BadRequestException;
import com.zz.tijian.expections.CommonException;
import com.zz.tijian.expections.ThirdPartyException;
import com.zz.tijian.handle.redis.CodeUtil;
import com.zz.tijian.mapper.UsersMapper;
import com.zz.tijian.service.UsersService;
import com.zz.tijian.utils.JwtTool;
import com.zz.tijian.utils.UserContext;
import com.zz.tijian.utils.ValidationUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisPool;

import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern;

/**
* @author 17958
* @description 针对表【users】的数据库操作Service实现
* @createDate 2024-06-13 12:04:17
*/
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users>
    implements UsersService {

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private CodeUtil codeUtil;

    @Autowired
    private JedisPool jedisPool;

    private final JwtTool jwtTool =new JwtTool();

    /**
     * 用户登录账号密码校验
     * @param loginDto
     * @return
     */
    @Override
    public Result<String> login(LoginDto loginDto) {
        //用户登录账号密码校验
        LambdaQueryWrapper<Users> queryWrapper=new LambdaQueryWrapper<>();
        Users one = this.getById(loginDto.getUserId());
        if(one==null){
            throw new BadRequestException("该用户不存在,请先注册!");
        }
        queryWrapper.eq(Users::getUserId,loginDto.getUserId());
        //Users one = this.getOne(queryWrapper);
        if(!loginDto.getPassword().equals(one.getPassword())){
            throw new CommonException("密码错误");
        }
        //成功返回状态码200 和token
        JwtTool jwtTool = new JwtTool();
        String token = jwtTool.createToken(one.getUserId(), one.getRealName(),one.getUserType());
        return Result.ok(token);
    }


    public Result<Boolean> register(Users regUser) {
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        regUser.setUserType(1);
        try {
            // TODO: 注册信息校验
            ValidationUtils.validate(regUser);

            int insert = usersMapper.insertUser(regUser);
            if (insert <= 0) {
                throw new CommonException("注册失败");
            }
            return Result.ok(true);
        } catch (DuplicateKeyException e) {
            // 处理主键重复异常
            throw new CommonException("用户已存在");
        } catch (Exception e) {
            // 处理其他异常
            throw new CommonException("注册失败：" + e.getMessage());
        }
    }

    @Override
    public Result<UserDetailVo> getUserDetail() {
        String userId = UserContext.currentUserId();
        Users user = this.getById(userId);
        UserDetailVo userDetailVo = new UserDetailVo();
        BeanUtils.copyProperties(user,userDetailVo);
        return Result.ok(userDetailVo);
    }

    @Override
    public Result<String> loginByCode(LoginDto loginDto) {
        String userId = loginDto.getUserId();

        String code = loginDto.getCode();
        // 校验手机号格式
        if(!Pattern.matches("^1[3-9]\\d{9}$", userId)){
            throw new BadRequestException("手机号格式错误");
        }
        LambdaQueryWrapper<Users> queryWrapper=new LambdaQueryWrapper<>();
        Users one = this.getById(loginDto.getUserId());
        if (one == null){
            throw new BadRequestException("用户不存在,请先进行注册!");
        }
        if(codeUtil.verifyCode(userId, code)){
            BeanUtils.copyProperties(one, loginDto);
            return login(loginDto);
        }
        return Result.error("验证码错误");
    }

    @Override
    public Result<Boolean> getCode(String userId){// zset限流

        if(!Pattern.matches("^1[3-9]\\d{9}$", userId)){
            throw new BadRequestException("手机号格式错误");
        }
        boolean limit = codeUtil.limit(userId);
        if(!limit){
            throw new CommonException("请求过于频繁");
        }
        LambdaQueryWrapper<Users> queryWrapper=new LambdaQueryWrapper<>();
        Users one = this.getById(userId);
        if (one == null){
            throw new BadRequestException("用户不存在,请先进行注册!");
        }
        boolean isSend = false;
        try {
            isSend = codeUtil.getRedisCode(userId);
            if(!isSend){
                throw new CommonException("获取验证码操作太频繁，请稍后再试");
            }
        } catch (ExecutionException | InterruptedException e) {
            throw new ThirdPartyException("短信服务暂时不可用,请稍后尝试访问");
        } catch (CommonException e){
            throw e;
        }
        return Result.ok(isSend);

    }

    @Override
    public Result<String> forgetPass(ForgetDto forgetDto) {
        if(!Pattern.matches("^1[3-9]\\d{9}$", forgetDto.getUserId())){
            throw new BadRequestException("手机号格式错误");
        }
        LambdaQueryWrapper<Users> queryWrapper=new LambdaQueryWrapper<>();
        Users one = this.getById(forgetDto.getUserId());
        if (one == null){
            throw new BadRequestException("用户不存在,请先进行注册!");
        }
        if(!codeUtil.verifyCode(forgetDto.getUserId(), forgetDto.getCode())){
            throw new BadRequestException("验证码错误");
        }
        String token = jwtTool.createToken(forgetDto.getUserId(), forgetDto.getCode(), 1);
        String key = "resetPassToken"+ forgetDto.getUserId();
        jedisPool.getResource().setex(key, 60*5, token);
        return Result.ok(token);
    }

    @Override
    public Result<Boolean> resetPass(ResetPassDto resetPassDto) {
        CurrentUserInfo currentUserInfo = jwtTool.parseToken(resetPassDto.getToken());
        if(currentUserInfo == null){
            throw new BadRequestException("已超时,请重试");
        }
        String token = jedisPool.getResource().get("resetPassToken" + currentUserInfo.getUserId());
        if(!token.equals(resetPassDto.getToken())){
            throw new BadRequestException("已超时,请重试");
        }
        if(resetPassDto.getPassword()==null||resetPassDto.getPassword().trim().length()==0){
            throw new BadRequestException("密码不能为空");
        }
        Users one = this.getById(currentUserInfo.getUserId());
        one.setPassword(resetPassDto.getPassword());
        this.updateById(one);
        jedisPool.getResource().del("resetPassToken" + currentUserInfo.getUserId());
        return Result.ok(true);
        // TODO: redis校验
    }
}




